package com.tcm.user.service;

import cn.hutool.core.util.ObjectUtil;
import com.base.core.exception.ServiceException;
import com.base.core.lang.StringUtils;
import com.base.core.utils.R;
import com.base.sms.service.verification.DefaultVerificationCodeService;
import com.tcm.user.constants.enums.BusinessCodeEnum;
import com.tcm.user.constants.enums.LoginTypeEnum;
import com.tcm.user.model.dto.LoginAuthDTO;
import com.tcm.user.model.dto.UserBaseInfoDTO;
import com.tcm.user.model.query.LoginAuthQuery;
import com.tcm.user.model.entity.LoginAuth;
import com.tcm.user.persistence.LoginAuthPersisService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@DubboService(version = "1.0.0", delay = -1)
public class UserServiceImpl implements UserService {

    @Autowired
    private LoginAuthPersisService loginAuthPersisService;

    @Autowired
    private DefaultVerificationCodeService defaultVerificationCodeService;

    @Override
    public R save(LoginAuth loginAuth) throws ServiceException {
        try{
            Long id = loginAuthPersisService.save(loginAuth);
            return R.success(id);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }

    }

    @Override
    public R update(LoginAuth loginAuth) {
        try{
            int ret = loginAuthPersisService.update(loginAuth);
            if(ret > 0){
                return R.success();
            }
        }catch (Exception e){
           return R.fail("小伙伴太热情了，请稍后再试");
        }
        return R.fail();
    }

    @Override
    public R findByUsername(String identifier, String clientType) {
        try{
            LoginAuth loginAuth = loginAuthPersisService.findByUsername(identifier, clientType);
            return R.success(loginAuth);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }
    }

    @Override
    public R findByMobile(String mobile, String clientType) {
        try{
            LoginAuth loginAuth = loginAuthPersisService.findByMobile(mobile, clientType);
            return R.success(loginAuth);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }
    }

    /**
     * 通过手机号批量查询账户基本信息
     * @param mobileList
     * @param clientType
     * @return
     */
    @Override
    public R queryByMobile(List<String> mobileList, String clientType) {

        try{
            List<LoginAuthDTO> loginAuthDTOS = loginAuthPersisService.queryByMobile(mobileList, clientType);
            if(loginAuthDTOS == null){
                return R.success(null);
            }
            List<UserBaseInfoDTO> userBaseInfoDTOList;
            userBaseInfoDTOList = loginAuthDTOS.stream().map(loginAuthDTO -> {
                UserBaseInfoDTO loginAuthMap = new UserBaseInfoDTO();
                loginAuthMap.setUsername(loginAuthDTO.getUsername());
                loginAuthMap.setAvatar(loginAuthDTO.getAvatar());
                loginAuthMap.setNickname(loginAuthDTO.getNickname());
                loginAuthMap.setId(loginAuthDTO.getId());
                loginAuthMap.setMobile(loginAuthDTO.getMobile());
                return loginAuthMap;
            }).collect(Collectors.toList());
            return R.success(userBaseInfoDTOList);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }
    }

    @Override
    public R findByUserId(Long userId, String clientType) {
        try{
            return loginAuthPersisService.findByUserId(userId, clientType);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }
    }

    /**
     * 获取单条数数据
     *
     * @param loginAuthQuery
     * @return
     */
    @Override
    public R queryUser(LoginAuthQuery loginAuthQuery) throws ServiceException{
        try {
            if(ObjectUtil.isNull(loginAuthQuery.getId())){
                return R.fail(BusinessCodeEnum.USER_ID_NOT_FOUND);
            }
            if(StringUtils.isBlank(loginAuthQuery.getClientType())){
                return R.fail(BusinessCodeEnum.USER_ID_NOT_FOUND);
            }
            LoginAuth loginAuth = new LoginAuth();
            BeanUtils.copyProperties(loginAuthQuery, loginAuth);
            String loginType = loginAuthQuery.getLoginType();
            if (loginType.equals(LoginTypeEnum.SMS.type())){
                loginAuth.setMobile(loginAuthQuery.getPrincipal());
            }else if (loginType.equals(LoginTypeEnum.PWD.type())){
                loginAuth.setUsername(loginAuthQuery.getPrincipal());
            }else if (loginType.equals(LoginTypeEnum.PHONE_PWD.type())){
                loginAuth.setMobile(loginAuthQuery.getPrincipal());
            }
            return loginAuthPersisService.queryUser(loginAuth);
        }catch (Exception e){
            return R.fail(BusinessCodeEnum.FAILED_TO_QUERY_USER);
        }
    }

    @Override
    public R changeCredential(LoginAuthQuery userParams) {
        try{
            if(ObjectUtil.isNull(userParams)){
                return R.fail(BusinessCodeEnum.USER_PARAMS_NOT_FOUND);
            }
            String password = userParams.getCredential();
            String clientType = userParams.getClientType();
            Long userId = userParams.getId();
            if (StringUtils.isEmpty(password)) {
                return R.fail(BusinessCodeEnum.PASSWORD_NOTFOUND);
            }

            if (ObjectUtil.isEmpty(userId)) {
                return R.fail(BusinessCodeEnum.USER_ID_NOT_FOUND);
            }

            if (ObjectUtil.isEmpty(clientType)) {
                return R.fail(BusinessCodeEnum.CLIENT_TYPE_PARAMS_NOT_FOUND);
            }
            return loginAuthPersisService.changeCredential(userParams);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }
    }

    @Override
    public R changeUsername(LoginAuthQuery userParams) {
        try{
            if(ObjectUtil.isNull(userParams)){
                return R.fail(BusinessCodeEnum.USER_PARAMS_NOT_FOUND);
            }
            Long userId = userParams.getId();
            if (ObjectUtil.isEmpty(userParams.getPrincipal())) {
                return R.fail(BusinessCodeEnum.IDENTIFIER_NOT_EXISTS);
            }

            if (ObjectUtil.isEmpty(userParams.getClientType())) {
                return R.fail(BusinessCodeEnum.CLIENT_TYPE_PARAMS_NOT_FOUND);
            }

            if(ObjectUtil.isEmpty(userId)){
                return R.fail(BusinessCodeEnum.USER_ID_NOT_FOUND);
            }

            R login = loginAuthPersisService.checkUsernameExists(userParams.getPrincipal(),
                    userId, userParams.getClientType());
            if (login.isSuccess()) {
                Map ret = (Map)login.getData();
                if((Boolean) ret.get("isUserExists")){
                    return R.fail(BusinessCodeEnum.IDENTIFIER_EXISTS);
                }
            }
            return loginAuthPersisService.changeUsername(userParams);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }
    }

    @Override
    public R changeMobile(LoginAuthQuery userParams) {
        try{
            if(ObjectUtil.isNull(userParams)){
                return R.fail(BusinessCodeEnum.USER_PARAMS_NOT_FOUND);
            }
            Long userId = userParams.getId();
            if (ObjectUtil.isEmpty(userParams.getPrincipal())) {
                return R.fail(BusinessCodeEnum.IDENTIFIER_NOT_EXISTS);
            }

            if (ObjectUtil.isEmpty(userParams.getClientType())) {
                return R.fail(BusinessCodeEnum.CLIENT_TYPE_PARAMS_NOT_FOUND);
            }

            if(ObjectUtil.isEmpty(userId)){
                return R.fail(BusinessCodeEnum.USER_ID_NOT_FOUND);
            }

            if(ObjectUtil.isNotEmpty(userParams.getCredential())){
                String code = userParams.getCredential();
                //验证短信
                boolean verify = defaultVerificationCodeService.verify(userParams.getPrincipal(), code, null);
                if(!verify){
                    return R.fail(BusinessCodeEnum.SMS_CODE_HAS_ERROR);
                }
            }

            R login = loginAuthPersisService.checkMobileExists(userParams.getPrincipal(),
                    userId, userParams.getClientType());
            if (login.isSuccess()) {
                Map ret = (Map)login.getData();
                if((Boolean) ret.get("isMobileExists")){
                    return R.fail(BusinessCodeEnum.SMS_PHONE_ALREADY_EXISTS);
                }
            }
            return loginAuthPersisService.changeMobile(userParams);
        }catch (Exception e){
            return R.fail("小伙伴太热情了，请稍后再试");
        }
    }
}
